<template>
    <div :class="wrapClass" class="text-black">
        <div ref="textRef" class="leading-relaxed break-words">
            <div v-if="!inversion">
                <div v-if="!asRawText" class="md-body"  v-html="text">
                </div>
                <div v-else class="whitespace-pre-wrap" v-text="text"></div>
            </div>
            <div v-else class="whitespace-pre-wrap">
                {{ text }}
                <template v-if="loading && !text">
                    <span class="w-[4px] h-[20px] block animate-blink"></span>
                </template>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">
    import MarkdownIt from 'markdown-it';
    import mdKatex from '@traptitech/markdown-it-katex';
    import mila from 'markdown-it-link-attributes';
    import hljs from 'highlight.js';
    import {copyToClipboard} from '/@/utils/copy';
    import other from '/@/utils/other';
    import { useI18n } from 'vue-i18n';

    const {t} = useI18n();
    //是否移动端设备
    const isMobile = ref(other.isMobile()|false);
    //设置props参数
    const props = defineProps({
        text: {
            type:String,
            default:''
        },
        asRawText: {
            type:Boolean,
            default:false
        },
        inversion: {
            type:Boolean,
            default:false
        },
        error: {
            type:Boolean,
            default:false
        },
        loading: {
          type:Boolean,
          default:false
        },
    });
    //文本引用
    const textRef = ref<HTMLDivElement | null>(null);
    //文本样式
    const wrapClass = computed(() => [
            'text-wrap',
            'rounded-md',
            isMobile.value? 'p-2' : 'px-3 py-2',
            props.inversion?'bg-[#70c0e8]':'bg-[#f4f6f8]',
            props.inversion?'message-request':'message-reply',
            {'text-red-500':props.error && props.text}
        ]);
    //MarkdownIt配置
    const mdi=new MarkdownIt({
        html:false,
        linkify:true,
        typographer:true,
        highlight:(code,language) => {
           const validLang =!!(language && hljs.getLanguage(language));
           if(validLang){
               const lang = lang ?? '';
               return highlightBlock(hljs.highlight(code, {language:lang}).value,lang);
           }
           return highlightBlock(hljs.highlightAuto(code).value,'');
        },
    });
    mdi.use(mila,{attrs:{target:'_blank',rel:'noopener noreferrer'}});
    mdi.use(mdKatex,{blockClass:'katemath-block rounded-md p-[10px]',errorColor:'#cc0000'});
    //text转换
    const text=computed(() => {
        const value=props.text ?? '';
        if(props.asRawText ){
            return mdi.render(value);
        }
        return value;
    });
    //代码块高亮
    const highlightBlock = (code:string,lang?:string) => {
        return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span>
            <span class="code-block-header__copy">{{t('chat.copy')}}</span></div>
            <code class="hljs code-block-body ${lang}">${code}</code></pre>`;
    };
    //添加复制功能
    onMounted(() => {
       addCopyEvents();
    });
    //更新
    onUpdated(() => {
        addCopyEvents();
    });
    //卸载
    onUnmounted(() => {
        removeCopyEvents();
    });
    //添加复制事件
    function addCopyEvents() {
        if(textRef.value){
            const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy');
            copyBtn.forEach(btn => {
                btn.addEventListener('click', () => {
                    const code=btn.parentElement?.nextElementSibling?.textContent;
                    if(code){
                        copyToClipboard(code)
                            .then(() => {
                                btn.textContent = '复制成功';
                                setTimeout(() => {
                                    btn.textContent = '复制';
                                },1000);
                            });
                    }
                });
            });
        }
    }
    //移除复制事件
    function removeCopyEvents() {
        if(textRef.value){
            const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy');
            copyBtn.forEach(btn => {
                btn.removeEventListener('click', () => {});
            });
        }
    }

</script>